#! /usr/bin/python3
# -*- coding: utf-8 -*-

###########################################################################
# Copyright 2019 (C) Hui Lan <hui.lan@cantab.net>
# Written permission must be obtained from the author for commercial uses.
###########################################################################
import threading

from WordFreq import WordFreq
from wordfreqCMD import youdao_link, sort_in_descending_order
from UseSqlite import InsertQuery, RecordQuery
import pickle_idea, pickle_idea2
import os
import random, glob
from datetime import datetime
from flask import Flask, request, redirect, render_template, url_for, session, abort, flash, get_flashed_messages
from difficulty import get_difficulty_level, text_difficulty_level, user_difficulty_level
import hashlib
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput



app = Flask(__name__)
app.secret_key = 'lunch.time!'

# path_prefix = '/var/www/wordfreq/wordfreq/'
path_prefix = './' # comment this line in deployment

#获取随机图片
def get_random_image(path):
    img_path = random.choice(glob.glob(os.path.join(path, '*.jpg')))
    return img_path[img_path.rfind('/static'):]

#获取随机标题
def get_random_ads():
    ads = random.choice(['个性化分析精准提升', '你的专有单词本', '智能捕捉阅读弱点，针对性提高你的阅读水平'])
    return ads + '。 <a href="/signup">试试</a>吧！'

#获取文章总数(修改)
def total_number_of_essays():
    rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
    #rq.instructions("SELECT * FROM article")
    #尽量避免使用select *语法，如果有索引的话
    rq.instructions("SELECT `article_id`,`text`,`source`,`date`,`level`,`question` FROM article")
    rq.do()
    result = rq.get_results()
    return  len(result)

#加载历史记录单词
def load_freq_history(path):
    d = {}
    if os.path.exists(path):
        d = pickle_idea.load_record(path)
    else:
        # windows不支持
        # os.mknod(path)
        f = open(path,'w')
        f.close()
    return d

#验证用户登录
def verify_user(username, password):
    rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
    rq.instructions_with_parameters("SELECT `name`,`password`,`start_date`,`expiry_date` FROM user WHERE name=? AND password=?", (username, password))
    rq.do_with_parameters()
    result = rq.get_results()
    return result != []

#修改密码
def chg_pwd(username,newpassword):
    rq = InsertQuery(path_prefix + 'static/wordfreqapp.db')
    rq.instructions_with_parameters("UPDATE user SET `password`=? where `name`=?",(newpassword, username))
    rq.do_with_parameters()


#添加用户
def add_user(username, password):
    start_date = datetime.now().strftime('%Y%m%d')
    expiry_date = '20211230'
    rq = InsertQuery(path_prefix + 'static/wordfreqapp.db')
    rq.instructions("INSERT INTO user Values ('%s', '%s', '%s', '%s')" % (username, password, start_date, expiry_date))
    rq.do()

#检查用户是否可用
def check_username_availability(username):
    rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
    rq.instructions("SELECT `name`,`password`,`start_date`,`expiry_date` FROM user WHERE name='%s'" % (username))
    rq.do()
    result = rq.get_results()
    return  result == []

#获取用户到期时间
def get_expiry_date(username):
    rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
    rq.instructions("SELECT expiry_date FROM user WHERE name='%s'" % (username))
    rq.do()
    result = rq.get_results()
    if len(result) > 0:
        return  result[0]['expiry_date']
    else:
        return '20191024'



def within_range(x, y, r):
    return x > y and abs(x - y) <= r

#获取文章标题
def get_article_title(s):
    return s.split('\n')[0]

#获取文章内容
def get_article_body(s):
    lst = s.split('\n')
    lst.pop(0) # remove the first line
    return '\n'.join(lst)

def get_today_article(user_word_list, articleID):

    rq = RecordQuery(path_prefix + 'static/wordfreqapp.db')
    if articleID == None:
        rq.instructions("SELECT `article_id`,`text`,`source`,`date`,`level`,`question` FROM article")
    else:
        rq.instructions('SELECT `article_id`,`text`,`source`,`date`,`level`,`question` FROM article WHERE article_id=%d' % (articleID))
    rq.do()
    result = rq.get_results()
    random.shuffle(result)

    # Choose article according to reader's level
    d1 = load_freq_history(path_prefix + 'static/frequency/frequency.p')
    d2 = load_freq_history(path_prefix + 'static/words_and_tests.p')
    d3 = get_difficulty_level(d1, d2)

    d = {}
    d_user = load_freq_history(user_word_list)
    user_level = user_difficulty_level(d_user, d3) # more consideration as user's behaviour is dynamic. Time factor should be considered.
    random.shuffle(result) # shuffle list
    d = random.choice(result)
    text_level = text_difficulty_level(d['text'], d3)
    if articleID == None:
        for reading in result:
            text_level = text_difficulty_level(reading['text'], d3)
            factor = random.gauss(0.8, 0.1) # a number drawn from Gaussian distribution with a mean of 0.8 and a stand deviation of 1
            if within_range(text_level, user_level, (8.0 - user_level)*factor):
                d = reading
                break

    s = '<div class="alert alert-success" role="alert">According to your word list, your level is <span class="badge bg-success">%4.2f</span>  and we have chosen an article with a difficulty level of <span class="badge bg-success">%4.2f</span> for you.</div>' % (user_level, text_level)
    s += '<p class="text-muted">Article added on: %s</p>' % (d['date'])
    s += '<div class="p-3 mb-2 bg-light text-dark">'
    article_title = get_article_title(d['text'])
    article_body = get_article_body(d['text'])
    s += '<p class="display-3"><font size=+2>%s</font></p>' % (article_title)
    s += '<p class="lead"><font id="article" size=+2>%s</font></p>' % (article_body)
    s += '<p><small class="text-muted">%s</small></p>' % (d['source'])
    s += '<p><b>%s</b></p>' % (get_question_part(d['question']))
    s = s.replace('\n', '<br/>')
    s += '%s' % (get_answer_part(d['question']))
    s += '</div>'
    session['articleID'] = d['article_id']
    return s

#检查d中是否有单词
def appears_in_test(word, d):
    if not word in d:
        return ''
    else:
        return ','.join(d[word])

#获取时间
def get_time():
    return datetime.now().strftime('%Y%m%d%H%M') # upper to minutes

#获取问题部分
def get_question_part(s):
    s = s.strip()
    result = []
    flag = 0
    for line in s.split('\n'):
        line = line.strip()
        if line == 'QUESTION':
            result.append(line)
            flag = 1
        elif line == 'ANSWER':
            flag = 0
        elif flag == 1:
            result.append(line)
    return '\n'.join(result)

#获取回答部分
def get_answer_part(s):
    s = s.strip()
    result = []
    flag = 0
    for line in s.split('\n'):
        line = line.strip()
        if line == 'ANSWER':
            flag = 1
        elif flag == 1:
            result.append(line)
    # https://css-tricks.com/snippets/javascript/showhide-element/
    js = '''
<script type="text/javascript">

    function toggle_visibility(id) {
       var e = document.getElementById(id);
       if(e.style.display == 'block')
          e.style.display = 'none';
       else
          e.style.display = 'block';
    }
</script>   
    '''
    html_code = js
    html_code += '\n'
    html_code += '<button onclick="toggle_visibility(\'answer\');">ANSWER</button>\n'
    html_code += '<div id="answer" style="display:none;">%s</div>\n' % ('\n'.join(result))
    return html_code

#获取消息
def get_flashed_messages_if_any():
    messages = get_flashed_messages()
    s = ''
    for message in messages:
        s += '<div class="alert alert-warning" role="alert">'
        s += 'Congratulations! {message}'
        s += '</div>'
    return s

#重置（文章和选择单词）
@app.route("/<username>/reset", methods=['GET', 'POST'])
def user_reset(username):
    if request.method == 'GET':
        session['articleID'] = None
        return redirect(url_for('userpage', username=username))
    else:
        return 'Under construction'

#标记单词
@app.route("/mark", methods=['GET', 'POST'])
def mark_word():
    if request.method == 'POST':
        d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
        lst_history = pickle_idea.dict2lst(d)
        lst = []
        for word in request.form.getlist('marked'):
            lst.append((word, 1))
        d = pickle_idea.merge_frequency(lst, lst_history)
        pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')
        return redirect(url_for('mainpage'))
    else:
        return 'Under construction'


#显示主界面
@app.route("/", methods=['GET', 'POST'])
def mainpage():
    if request.method == 'POST':  # when we submit a form
        content = request.form['content']
        f = WordFreq(content)
        lst = f.get_freq()
        page = '<form method="post" action="/mark">\n'
        count = 1
        for x in lst:
            page += '<p><font color="grey">%d</font>: <a href="%s">%s</a> (%d)  <input type="checkbox" name="marked" value="%s"></p>\n' % (count, youdao_link(x[0]), x[0], x[1], x[0])
            count += 1
        page += ' <input type="submit" value="确定并返回"/>\n'
        page += '</form>\n'
        # save history 
        d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
        lst_history = pickle_idea.dict2lst(d)
        d = pickle_idea.merge_frequency(lst, lst_history)
        pickle_idea.save_frequency_to_pickle(d, path_prefix + 'static/frequency/frequency.p')

        return page
    elif request.method == 'GET': # when we load a html page
        page = '''
             <html lang="zh">
               <head>
               <meta charset="utf-8">
               <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />
               <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

                 <title>EnglishPal 英文单词高效记</title>

               </head>
               <body>
        '''
        page += '<div class="container-fluid">'
        page += '<p><b><font size="+3" color="red">English Pal - Learn English smartly!</font></b></p>'
        if session.get('logged_in'):
            page += ' <a href="%s">%s</a></p>\n' % (session['username'], session['username'])
        else:
            page += '<p><a href="/login">登录</a>  <a href="/signup">成为会员</a> <a href="/static/usr/instructions.html">使用说明</a></p>\n'
        #page += '<p><img src="%s" width="400px" alt="advertisement"/></p>' % (get_random_image(path_prefix + 'static/img/'))
        page += '<p><b>%s</b></p>' % (get_random_ads())
        page += '<div class="alert alert-success" role="alert">共有文章 <span class="badge bg-success"> %d </span> 篇</div>' % (total_number_of_essays())
        page += '<p>粘帖1篇文章 (English only)</p>'
        page += '<form method="post" action="/">'
        page += ' <textarea name="content" rows="10" cols="120"></textarea><br/>'
        page += ' <input type="submit" value="get文章中的词频"/>'
        page += ' <input type="reset" value="清除"/>'
        page += '</form>'
        d = load_freq_history(path_prefix + 'static/frequency/frequency.p')
        if len(d) > 0:
            page += '<p><b>最常见的词</b></p>'
            for x in sort_in_descending_order(pickle_idea.dict2lst(d)):
                if x[1] <= 99:
                    break
                page += '<a href="%s">%s</a> %d\n' % (youdao_link(x[0]), x[0], x[1])

        page += ' <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>'
        page += '</div>'
        page += '</body></html>'
        return page

#用户标记单词页
@app.route("/<username>/mark", methods=['GET', 'POST'])
def user_mark_word(username):
    username = session[username]
    user_freq_record = path_prefix + 'static/frequency/' +  'frequency_%s.pickle' % (username)
    if request.method == 'POST':
        d = load_freq_history(user_freq_record)
        lst_history = pickle_idea2.dict2lst(d)
        lst = []
        for word in request.form.getlist('marked'):
            # word.replace('<','')
            # word.replace('>','')
            lst.append((word, [get_time()]))
        d = pickle_idea2.merge_frequency(lst, lst_history)
        pickle_idea2.save_frequency_to_pickle(d, user_freq_record)
        return redirect(url_for('userpage', username=username))
    else:
        return 'Under construction'

#不熟悉单词
@app.route("/<username>/<word>/unfamiliar", methods=['GET', 'POST'])
def unfamiliar(username,word):
    user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
    pickle_idea.unfamiliar(user_freq_record,word)
    session['thisWord'] = word  # 1. put a word into session
    session['time'] = 1
    return redirect(url_for('userpage', username=username))

#熟悉单词
@app.route("/<username>/<word>/familiar", methods=['GET', 'POST'])
def familiar(username,word):
    user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
    pickle_idea.familiar(user_freq_record,word)
    session['thisWord'] = word  # 1. put a word into session
    session['time'] = 1
    return redirect(url_for('userpage', username=username))

#删除单词
@app.route("/<username>/<word>/del", methods=['GET', 'POST'])
def deleteword(username,word):
    user_freq_record = path_prefix + 'static/frequency/' + 'frequency_%s.pickle' % (username)
    pickle_idea2.deleteRecord(user_freq_record,word)
    flash('<strong>{word}</strong> is no longer in your word list.')
    return redirect(url_for('userpage', username=username))



#用户页
@app.route("/<username>", methods=['GET', 'POST'])
def userpage(username):

    if not session.get('logged_in'):
        return '<p>请先<a href="/login">登录</a>。</p>'

    user_expiry_date = session.get('expiry_date')
    if datetime.now().strftime('%Y%m%d') > user_expiry_date:
        return '<p>账号 %s 过期。</p><p>为了提高服务质量，English Pal 收取会员费用， 每天0元。</p> <p>请决定你要试用的时间长度，扫描下面支付宝二维码支付。 支付时请注明<i>English Pal Membership Fee</i>。 我们会于12小时内激活账号。</p><p><img src="static/donate-the-author-hidden.jpg" width="120px" alt="支付宝二维码" /></p><p>如果有问题，请加开发者微信 torontohui。</p> <p><a href="/logout">登出</a></p>' % (username)


    username = session.get('username')

    user_freq_record = path_prefix + 'static/frequency/' +  'frequency_%s.pickle' % (username)

    if request.method == 'POST':  # when we submit a form
        content = request.form['content']
        f = WordFreq(content)
        lst = f.get_freq()
        page = '<meta charset="UTF8">'
        page += '<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />'
        page += '<p>勾选不认识的单词</p>'
        page += '<form method="post" action="/%s/mark">\n' % (username)
        page += ' <input type="submit" name="add-btn" value="加入我的生词簿"/>\n'
        count = 1
        words_tests_dict = pickle_idea.load_record(path_prefix + 'static/words_and_tests.p')
        for x in lst:
            page += '<p><font color="grey">%d</font>: <a href="%s" title="%s">%s</a> (%d)  <input type="checkbox" name="marked" value="%s"></p>\n' % (count, youdao_link(x[0]), appears_in_test(x[0], words_tests_dict), x[0], x[1], x[0])
            count += 1
        page += '</form>\n'
        return page

    elif request.method == 'GET': # when we load a html page
        page = '<meta charset="UTF8">\n'
        page += '<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=3.0, user-scalable=yes" />\n'
        page += '<meta name="format-detection" content="telephone=no" />\n' # forbid treating numbers as cell numbers in smart phones
        page += '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">'
        page += '''
                <style>
                    mark {
                        background-color:yellow;//设置背景颜色
                        color:white;//设置文字颜色
                        }
                </style>
                '''
        page += '<title>EnglishPal Study Room for %s</title>' % (username)
        page += '<div class="container-fluid">'
        page += '<p><b>English Pal for <font color="red"><a href="/%s//chgpwd">%s</a></font></b> <a class="btn btn-secondary" href="/logout" role="button">登出</a></p>' % (username,username)
        page += get_flashed_messages_if_any()
        page += '<p><b>阅读文章并回答问题</b></p>\n'
        page += '<p><a class="btn btn-success" href="/%s/reset" role="button"> 下一篇 Next Article </a></p>' % (username)
        page += '<div id="text-content">%s</div>'  % (get_today_article(user_freq_record, session['articleID']))
        page += '<p><b>收集生词吧</b> （可以在正文中划词，也可以复制黏贴）</p>'
        page += '<button id="cancel_highlight" onclick="cancelBtnHandler()">取消高亮</button>'
        page += '<button id="show_highlight" onclick="showBtnHandler()">显示高亮</button>'
        page += '<form method="post" action="/%s">' % (username)
        page += ' <textarea name="content" id="selected-words" rows="10" cols="120"></textarea><br/>'
        page += ' <input type="submit" value="get 所有词的频率"/>'
        page += ' <input type="reset" value="清除"/>'
        page += '</form>\n'
        #修改高亮部分
        page += ''' 
                 <script type="text/javascript">
                 
                   function cancelBtnHandler(){
                        cancel_highLight();
                        document.getElementById("text-content").removeEventListener("click", fillinWord, false);
                        document.getElementById("text-content").removeEventListener("touchstart", fillinWord, false);
                        document.getElementById("text-content").addEventListener("click", fillinWord2, false);
                        document.getElementById("text-content").addEventListener("touchstart", fillinWord2, false);
                   }
                   
                   function showBtnHandler(){
                        document.getElementById("text-content").removeEventListener("click", fillinWord2, false);
                        document.getElementById("text-content").removeEventListener("touchstart", fillinWord2, false);
                        document.getElementById("text-content").addEventListener("click", fillinWord, false);
                        document.getElementById("text-content").addEventListener("touchstart", fillinWord, false);
                        highLight();
                   }
                    
                   function getWord(){ 
                       var word = window.getSelection?window.getSelection():document.selection.createRange().text;
                       return word;
                   }
                   
                   function highLight(){
                        var txt=document.getElementById("article").innerText;
                        var list=document.getElementById("selected-words").value.split(" ");
                        var list2=document.getElementById("selected-words2").value.split(" ");
                        for(var i=0;i<list.length;++i){
                            list[i]=list[i].replace(/(^\s*)|(\s*$)/g, "");
                            if(list[i]!=""&&"<mark>".indexOf(list[i])==-1&&"</mark>".indexOf(list[i])==-1){
                                txt=txt.replace(new RegExp(list[i],"g"),"<mark>"+list[i]+"</mark>");
                            }
                        }
                        for(var i=0;i<list2.length;++i){
                            list2[i]=list2[i].replace(/(^\s*)|(\s*$)/g, "");
                            if(list2[i]!=""&&"<mark>".indexOf(list2[i])==-1&&"</mark>".indexOf(list2[i])==-1){
                                txt=txt.replace(new RegExp(list2[i],"g"),"<mark>"+list2[i]+"</mark>");
                            }
                        }
                        document.getElementById("article").innerHTML=txt;
                   }
                   
                    function cancel_highLight(){
                        var txt=document.getElementById("article").innerText;
                        var list=document.getElementById("selected-words").value.split(" ");
                        var list2=document.getElementById("selected-words2").value.split(" "); 
                        for(var i=0;i<list.length;++i){
                            list[i]=list[i].replace(/(^\s*)|(\s*$)/g, "");
                            if(list[i]!=""){
                                txt=txt.replace("<mark>"+list[i]+"</mark>","list[i]");
                            }
                        }
                        for(var i=0;i<list2.length;++i){
                            list2[i]=list2[i].replace(/(^\s*)|(\s*$)/g, "");
                            if(list2[i]!=""){
                                txt=txt.replace("<mark>"+list[i]+"</mark>","list[i]");
                            }
                        }
                        document.getElementById("article").innerHTML=txt;
                   }
                   
                   function fillinWord(){
                       var element = document.getElementById("selected-words");
                       element.value = element.value + " " + getWord();
                       highLight();
                   }
                   
                   function fillinWord2(){
                       var element = document.getElementById("selected-words");
                       element.value = element.value + " " + getWord();
                       cancel_highLight();
                   }
                   showBtnHandler();

       
                 </script>
                 '''
        if session.get('thisWord'):
            page += '''
                   <script type="text/javascript">
                        //point to the anchor in the page whose id is aaa if it exists
                        window.onload = function(){
                            var element = document.getElementsByName("aaa");

                            if (element != null)
                                document.getElementsByName("aaa")[0].scrollIntoView(true);

                        }
                   </script> 
                   '''

        d = load_freq_history(user_freq_record)
        if len(d) > 0:
            page += '<p><b>我的生词簿</b></p>'
            page += '<form ></form>'
            lst = pickle_idea2.dict2lst(d)

            lst2 = []
            words = ''
            for t in lst:
                lst2.append((t[0], len(t[1])))
            for x in sort_in_descending_order(lst2):
                word = x[0]
                freq = x[1]
                words += word+' '

                if session.get('thisWord') == x[0] and session.get('time') == 1:
                    page += '<a name="aaa"></a>'    # 3. anchor
                    session['time'] = 0   # discard anchor
                if isinstance(d[word], list): # d[word] is a list of dates
                    if freq > 1:
                        page += '<p class="new-word"> <a class="btn btn-light" href="%s" role="button">%s</a>(<a title="%s">%d</a>) <a class="btn btn-success" href="%s/%s/familiar" role="button">熟悉</a> <a class="btn btn-warning" href="%s/%s/unfamiliar" role="button">不熟悉</a>  <a class="btn btn-danger" href="%s/%s/del" role="button">删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
                    else:
                        page += '<p class="new-word"> <a class="btn btn-light" href="%s" role="button">%s</a>(<a title="%s">%d</a>) <a class="btn btn-success" href="%s/%s/familiar" role="button">熟悉</a> <a class="btn btn-warning" href="%s/%s/unfamiliar" role="button">不熟悉</a>  <a class="btn btn-danger" href="%s/%s/del" role="button">删除</a> </p>\n' % (youdao_link(word), word, '; '.join(d[word]), freq,username, word,username,word, username,word)
                elif isinstance(d[word], int): # d[word] is a frequency. to migrate from old format.
                    page += '<a href="%s">%s</a>%d\n' % (youdao_link(word), word, freq)
            page += '<input id="selected-words2" type="hidden" value="%s">\n' % words
        page += '<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>'
        page += '</div>'
        return page


def make_password(password):
    # 1.加盐,SECRET_KEY为加盐字符串,from ads.settings import SECRET_KEY
    password = app.secret_key + password
    # 2.开始加密
    # sha1_obj = hashlib.sha1()
    # sha1_obj.update(password.encode())
    # ret = sha1_obj.hexdigest()


    # sha1,md5两种加密算法类似,sha1加密后40位,md5加密后32位,sha1相对安全,但速度慢
    md5_obj = hashlib.md5()
    md5_obj.update(password.encode())
    ret = md5_obj.hexdigest()
    # print(ret)  # 201812424099946c9c5590be9754b94b
    # print(len(ret))  # 32
    return ret


### Sign-up, login, logout ###
@app.route("/signup", methods=['GET', 'POST'])
def signup():
    if request.method == 'GET':
        return render_template('signup.html')
    elif request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        if '<' in username:
            return "非法用户名。"
        if '<' in password:
            return "非法密码"

        available = check_username_availability(username)
        if not available:
            flash('用户名 %s 已经被注册。' % (username))
            return render_template('signup.html')
        elif len(password.strip()) < 4:
            return '密码过于简单。'
        else:
            password = make_password(password)
            add_user(username, password)
            verified = verify_user(username, password)
            if verified:
                session['logged_in'] = True
                session[username] = username
                session['username'] = username
                session['expiry_date'] = get_expiry_date(username)
                session['articleID'] = None
                return '<p>恭喜，你已成功注册， 你的用户名是 <a href="%s">%s</a>。</p>\
                <p><a href="/%s">开始使用</a> <a href="/">返回首页</a><p/>' % (username, username, username)
            else:
                return '用户名密码验证失败。'

@app.route("/<username>/chgpwd", methods=['GET', 'POST'])
def chgpwd(username):
    if request.method == 'GET':
        return render_template('chgpwd.html')
    elif request.method == 'POST':

        oldpassword = request.form['oldpassword']
        newpassword = request.form['newpassword']
        again = request.form['again']

        if '<' in newpassword:
            return "非法密码"

        if newpassword != again:
            return '两次输入密码不一致'

        oldpassword = make_password(oldpassword)
        verified = verify_user(username, oldpassword)
        if verified:
            newpassword = make_password(newpassword)
            is_chg = chg_pwd(username, newpassword)
            session['logged_in'] = False
            return redirect(url_for('mainpage'))
        else:
            return '密码错误。'

@app.route("/login", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        if not session.get('logged_in'):
            return render_template('login.html')
        else:
            return '你已登录 <a href="/%s">%s</a>。 登出点击<a href="/logout">这里</a>。' % (session['username'], session['username'])
    elif request.method == 'POST':
        # check database and verify user
        username = request.form['username']
        password = request.form['password']

        password = make_password(password)

        verified = verify_user(username, password)
        if verified:
            session['logged_in'] = True
            session[username] = username
            session['username'] = username
            user_expiry_date = get_expiry_date(username)
            session['expiry_date'] = user_expiry_date
            session['articleID'] = None
            return redirect(url_for('userpage', username=username))
        else:
            return '无法通过验证。'


@app.route("/logout", methods=['GET', 'POST'])
def logout():
    session['logged_in'] = False
    return redirect(url_for('mainpage'))




if __name__ == '__main__':



    # app.secret_key = os.urandom(16)
    # app.run(debug=False, port='6000')
    app.run(debug=True)
    # app.run(debug=True, port='6000')
    # app.run(host='0.0.0.0', debug=True, port='6000')
